/***************************************************************************
 *   Copyright © 2010 by Nikolay Kornaev                                   *
 *   n.kornaev@gmail.com                                                   *
 *                                                                         *
 *                    This file is part of neuma.                          *
 *                                                                         *
 *   neuma is free software; you can redistribute it and/or modify it      *
 *   under the terms of the GNU General Public License as published by     *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   neuma is distributed in the hope that it will be useful,              *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
 ***************************************************************************/

#pragma once

#include <QtGui/QAction>
#include <QtGui/QDoubleValidator>
#include <QtGui/QLineEdit>
#include <QtGui/QMainWindow>

class QComboBox;
class QGraphicsView;
class QLabel;
class QPrintDialog;
class QPrintPreviewWidget;

namespace Neuma
{
  static inline void qt_setupActionIcon(QAction *action, const QLatin1String &name)
  {
    QLatin1String imagePrefix(":/trolltech/dialogs/qprintpreviewdialog/images/");
    QIcon icon;
    icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
    icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
    action->setIcon(icon);
  }

  class LineEdit: public QLineEdit
  {
  Q_OBJECT
  public:
    LineEdit(QWidget* parent = 0) :
      QLineEdit(parent)
    {
      setContextMenuPolicy(Qt::NoContextMenu);
      connect(this, SIGNAL(returnPressed()), SLOT(handleReturnPressed()));
    }

  protected:
    void focusInEvent(QFocusEvent *e)
    {
      origText = text();
      QLineEdit::focusInEvent(e);
    }

    void focusOutEvent(QFocusEvent *e)
    {
      if (isModified() && !hasAcceptableInput())
        setText(origText);
      QLineEdit::focusOutEvent(e);
    }

  private slots:
    void handleReturnPressed()
    {
      origText = text();
    }

  private:
    QString origText;
  };

  class PrintPreviewMainWindow: public QMainWindow
  {
  public:
    PrintPreviewMainWindow(QWidget *parent) :
      QMainWindow(parent)
    {
    }
    QMenu *createPopupMenu()
    {
      return 0;
    }
  };

  class ZoomFactorValidator: public QDoubleValidator
  {
  public:
    ZoomFactorValidator(QObject* parent) :
      QDoubleValidator(parent)
    {
    }
    ZoomFactorValidator(qreal bottom, qreal top, int decimals, QObject *parent) :
      QDoubleValidator(bottom, top, decimals, parent)
    {
    }

    State validate(QString &input, int &pos) const
    {
      bool replacePercent = false;
      if (input.endsWith(QLatin1Char('%')))
      {
        input = input.left(input.length() - 1);
        replacePercent = true;
      }
      State state = QDoubleValidator::validate(input, pos);
      if (replacePercent)
        input += QLatin1Char('%');
      const int num_size = 4;
      if (state == Intermediate)
      {
        int i = input.indexOf(QLocale::system().decimalPoint());
        if ((i == -1 && input.size() > num_size) || (i != -1 && i > num_size))
          return Invalid;
      }
      return state;
    }
  };

  class DisplayWidget: public QWidget
  {
  Q_OBJECT

  public:
    DisplayWidget(QWidget *parent = 0);

  private slots:
    void fit(QAction *action);
    void zoomIn();
    void zoomOut();
    void navigate(QAction *action);
    void setMode(QAction *action);
    void pageNumEdited();
    void print();
    void pageSetup();
    void previewChanged();
    void zoomFactorChanged();

  public:
    void init(QPrinter *printer = 0);
    void layoutPages();
    void setupActions();
    void updateNavActions();
    void setFitting(bool on);
    bool isFitting();
    void updatePageNumLabel();
    void updateZoomFactor();

    QPrintDialog *printDialog;
    QPrintPreviewWidget *preview;
    QPrinter *printer;
    QGraphicsView *view;
    bool ownPrinter;
    bool initialized;

  private:
    QLineEdit *pageNumEdit;
    QLabel *pageNumLabel;
    QComboBox *zoomFactor;

    // actions:
    QActionGroup* navGroup;
    QAction *nextPageAction;
    QAction *prevPageAction;
    QAction *firstPageAction;
    QAction *lastPageAction;

    QActionGroup* fitGroup;
    QAction *fitWidthAction;
    QAction *fitPageAction;

    QActionGroup* zoomGroup;
    QAction *zoomInAction;
    QAction *zoomOutAction;

    QActionGroup* orientationGroup;
    QAction *portraitAction;
    QAction *landscapeAction;

    QActionGroup* modeGroup;
    QAction *singleModeAction;
    QAction *facingModeAction;
    QAction *overviewModeAction;

    QActionGroup *printerGroup;
    QAction *printAction;
    QAction *pageSetupAction;
  };
}
